package com.tianyu.inspection.service;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.tianyu.inspection.common.model.PageModel;
import com.tianyu.inspection.service.api.IPileCardService;
import com.tianyu.inspection.common.component.MapperModel;
import com.tianyu.inspection.entity.PileCard;
import com.tianyu.inspection.entity.PileCardType;
import com.tianyu.inspection.entity.model.OperateMo;
import com.tianyu.inspection.entity.model.QueryMo;
import com.tianyu.inspection.entity.vo.ServiceRo;
import com.tianyu.inspection.mapper.PileCardMapper;
import io.ocs.model.OcsSimpleModel;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Objects;

/**********************************
 * @Author YSW
 * @Description 桩牌服务
 * @Date 2021/1/18 - 09:37
 **********************************/

@Service
public class PileCardServiceImpl implements IPileCardService {

    @Resource
    private MapperModel mapperModel;

    @Resource
    private PileCardMapper pileCardMapper;

    @Resource
    private OcsSimpleModel ocsSimpleModel;

    /**
     * 加载管线点
     *
     * @param pipelineFile 管线文件
     * @param projectId    项目ID
     * @return 管线点
     */
    @Override
    public List<PileCard> loadPileCard(MultipartFile pipelineFile, Integer projectId) {
        List<PileCard> pileCards = new ArrayList<>();
        try {
            Document doc = new SAXReader().read(pipelineFile.getInputStream());
            Element messages = doc.getRootElement().elements("Document").get(0);
            List<Element> elements = messages.elements("Placemark");
            for (Element element: elements) {
                Element name = element.element("name");
                Element point = element.element("Point");
                if (Objects.nonNull(point) && Objects.nonNull(name)){
                    String[] coordinates = point.element("coordinates").getTextTrim().split(",");
                    PileCard pileCard = new PileCard();
                    pileCard.setSystemStakeNumber(name.getTextTrim());
                    pileCard.setLng(Double.valueOf(coordinates[0]));
                    pileCard.setLat(Double.valueOf(coordinates[1]));
                    pileCard.setAltitude(Float.valueOf(coordinates[2]));
                    pileCard.setProjectId(projectId);
                    pileCards.add(pileCard);
                }
            }
            return pileCards;
        } catch (DocumentException | IOException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 加载管线点
     *
     * @param pipelineFile 管线JSON文件
     * @param projectId    项目ID
     * @return 管线点
     */
    @Override
    @Transactional(rollbackFor = Exception.class, isolation = Isolation.REPEATABLE_READ, propagation = Propagation.REQUIRED)
    public ServiceRo uploadPileCard(MultipartFile pipelineFile, Integer projectId, Integer pipelineId, Integer pipelineStationId) {
        final List<PileCard> pileCards = loadPileCard(pipelineFile, projectId);
        final QueryWrapper<PileCard> wrapper = new QueryWrapper<>();
        wrapper.eq("project_id",projectId);
        final ArrayList<String> systemStakeNumbers = new ArrayList<>();
        pileCards.forEach(pileCard -> {
            pileCard.setPipelineId(pipelineId);
            pileCard.setPipelineStationId(pipelineStationId);
            if (pileCardMapper.selectCount(wrapper.clone().eq("system_stake_number",pileCard.getSystemStakeNumber())) > 0){
                systemStakeNumbers.add(pileCard.getSystemStakeNumber());
            }
        });
        if (systemStakeNumbers.size() > 0){
            return new ServiceRo().setResult(false).setData(systemStakeNumbers);
        }else {
            return new ServiceRo().setResult(pileCards.size() == pileCardMapper.batchInsert(pileCards));
        }
    }

    /**
     * 分页查询
     *
     * @param queryMo 参数模型
     * @return ModelMap
     */
    @Override
    public IPage<PileCard> searchListPage(QueryMo queryMo) {
        Map<Integer, String> pipelineMap = mapperModel.getPipelineMap(queryMo);
        Map<Integer, String> pipelineStationMap = mapperModel.getPipelineStationMap(queryMo);
        Map<Integer, PileCardType> pileCardTypeMap = mapperModel.getPileCardTypeMap();
        IPage<PileCard> page = PageModel.getModelPage(queryMo, pileCardMapper);
        page.getRecords().forEach(pileCard -> {
            final PileCardType pileCardType = pileCardTypeMap.get(pileCard.getPileCardTypeId());
            if (Objects.nonNull(pileCardType)){
                pileCard.setPileCardTypeName(pileCardType.getName());
                final String icon = pileCardType.getIcon();
                if (Objects.nonNull(icon)){
                    pileCard.setPileCardTypeIcon(ocsSimpleModel.getObjectUrl(icon));
                }
            }
            pileCard.setPipelineName(pipelineMap.get(pileCard.getPipelineId()));
            pileCard.setPipelineStationName(pipelineStationMap.get(pileCard.getPipelineStationId()));
            if (Objects.nonNull(pileCard.getSceneImage())){
                pileCard.setSceneImage(ocsSimpleModel.getObjectUrl(pileCard.getSceneImage()));
            }
        });
        return page;
    }


    /**
     * 通过ID等参数查询一条数据
     *
     * @param queryMo 参数集[实体ID 与 项目ID, 数据状态等]
     * @return 单条记录结果
     */
    @Override
    public PileCard selectOne(QueryMo queryMo) {
        if(Objects.nonNull(queryMo.getEqMap().get("id"))){
            PileCard pileCard = pileCardMapper.selectOne(new QueryWrapper<PileCard>().allEq(queryMo.getEqMap()));
            if (Objects.nonNull(pileCard) && Objects.nonNull(pileCard.getSceneImage())){
                pileCard.setSceneImage(ocsSimpleModel.getObjectUrl(pileCard.getSceneImage()));
            }
            return pileCard;
        }
        return null;
    }

    /**
     * 插入一条数据
     *
     * @param operateMo 实体对象
     * @return 是否操作成功
     */
    @Override
    public boolean insert(OperateMo operateMo) {
        ObjectMapper objectMapper = new ObjectMapper();
        PileCard pileCard = objectMapper.convertValue(operateMo.getEntity(), PileCard.class);
        return 1 == pileCardMapper.insert(pileCard);
    }

    /**
     * 通过ID删除一条数据
     *
     * @param queryMo 参数集[实体ID 与 项目ID, 数据状态等]
     * @return 是否操作成功
     */
    @Override
    public boolean delete(QueryMo queryMo) {
        if(Objects.nonNull(queryMo.getEqMap().get("id"))){
            return 1 == pileCardMapper.delete(new QueryWrapper<PileCard>().allEq(queryMo.getEqMap()));
        }
        return false;
    }

    /**
     * 插入一条数据
     *
     * @param operateMo 更新参数集
     * @return ModelMap
     */
    @Override
    public boolean update(OperateMo operateMo) {
        ObjectMapper objectMapper = new ObjectMapper();
        PileCard pileCard = objectMapper.convertValue(operateMo.getEntity(), PileCard.class);
        return 1 == pileCardMapper.update(pileCard,new QueryWrapper<PileCard>().allEq(operateMo.getEqMap()));
    }

    /**
     * 通过ID逻辑删除一条数据
     *
     * @param queryMo 参数集[实体ID 与 项目ID, 数据状态]
     * @return 是否操作成功
     */
    @Override
    public boolean logicallyDelete(QueryMo queryMo) {
        return 1 == pileCardMapper.update(
                new PileCard().setState(1),
                new QueryWrapper<PileCard>().allEq(queryMo.getEqMap())
        );
    }
}
